package com.example.springboot.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot.Exception.ServiceException;
import com.example.springboot.Untils.TokenUtils;
import com.example.springboot.common.Result;
import com.example.springboot.entity.User;
import com.example.springboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 雒鑫
 * Java Web
 */
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    //通过该注解 拿到spring容器当中userService的一个实例
    //通过该实例调用方法
    UserService userService;

    /*
    新增用户信息
     */
    @PostMapping("/add")
    public Result add(@RequestBody User user) {
        try {
            /*
            接收用户传来的信息 并进行判断
             */
            userService.save(user);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                return Result.error("插入数据错误");
            } else {
                return Result.error("系统错误");
            }

        }
        return Result.success();
    }

    /*
   修改用户信息
    */
    @PutMapping("/update")
    public Result update(@RequestBody User user) {
        userService.updateById(user);
        return Result.success();
    }

    /*
   删除单个用户信息
    */
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id) {
        User currentUser = TokenUtils.getCurrentUser();
        if (id.equals(currentUser.getId())) {
            throw new ServiceException("不能删除当前用户信息");
        }
        userService.removeById(id);
        return Result.success();
    }

    /*
   批量删除用户信息
    */
    @DeleteMapping("/delete/batch")
    public Result batchDelete(@RequestBody List<Integer> ids) {
        User currentUser = TokenUtils.getCurrentUser();
        if (currentUser != null && currentUser.getId() != null && ids.contains(currentUser.getId())) {
            throw new ServiceException("当前用户无法删除");
        }
        userService.removeBatchByIds(ids);
        return Result.success();
    }

    /*
  查询用户信息
   */
    @GetMapping("/selectAll")
    public Result seletcAll() {
        List<User> users = userService.list(new QueryWrapper<User>().orderByDesc("id"));//select * from user user by id desc
        return Result.success(users);
    }

    /*
根据id 查询用户信息
  */
    @GetMapping("/SeletcById/{id}")
    public Result SeletcById(@PathVariable Integer id) {
        //放回当前的用户信息
        /*
        返回结果只会是一个对象
         */
        User users = userService.getById(id);
        //将结果封装到Result当中
        return Result.success(users);
    }

    /*
    分页多条件模糊查询
    计算limit:(pageNum-1)*pageSize
     */
    @GetMapping("/selectByPage")
    public Result selectByPage(
            @RequestParam Integer pageNum,//当前是那一页（当前的页码）
            @RequestParam Integer pageSize,//当前页有多少条
            @RequestParam String username,
            @RequestParam String name) {
        /*
        分页一般返回两个数据: 一个是用户的列表 一个是用户的总数
         */
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>().orderByDesc("id");
        queryWrapper.like(StrUtil.isBlank(username), "username", username);
        queryWrapper.like(StrUtil.isBlank(name), "name", name);
        /*
        select *from `user`where username like  '%#{username}%'  and name like '%#{name}%')
         */

        Page<User> page = userService.page(new Page<>(pageNum, pageSize), queryWrapper);

        return Result.success(page);
    }

    //批量导出数据
    @GetMapping("/export")
    public void exportData(@RequestParam(required = false) String username,
                           @RequestParam(required = false) String name,
                           /*@RequestParam(required = false) String ids,*/
                           HttpServletResponse response) throws IOException {
        ExcelWriter writer = ExcelUtil.getWriter(true);

        //第一种全部导出
        /*QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StrUtil.isBlank(username), "username", username);
        queryWrapper.like(StrUtil.isBlank(name), "name", name);
        List<User> list = userService.list(queryWrapper);//查询出当前user表的所有数据*/
        List<User> list = new ArrayList<>();
        if (StrUtil.isBlank(username)&&StrUtil.isBlank(name)){
            list = userService.list();
        }

        writer.write(list, true);//获取所有的用户对象
        //导出excel文件所需要的游览器设置
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户信息表", "UTF-8") + ".xlsx");

        ServletOutputStream outputStream = response.getOutputStream();

        writer.flush(outputStream,true);
        writer.close();
        outputStream.flush();
        outputStream.close();

    }
    /*
    文件批量导入
     */

    //数据导入
    @PostMapping("/import")
    public Result importData(MultipartFile file) throws IOException {
        //1.获取流对象 里面存需要导入的数据
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        List<User> userList = reader.readAll(User.class);
        //写入数据到数据库
        try {
            userService.saveBatch(userList);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("文件导入出错");
        }
        return Result.success();
    }
    /* */

   /*
   根据姓名进行多条件查询时 返回的结果不再是单个的对象 结果应该放进集合当中 否则会报错
   细节：根据条件查询的时候 如果不确定返回的结果有几个 那就统一返回一个集合对象
*/
   /* @GetMapping ("/SeletcByName/{name}")
    public Result SeletcByName(@PathVariable String name) {
        //放回当前的用户信息
        *//*
        返回的结果是多个对象
         *//*
        List<User> users1= userService.selectByname(name);
        //将结果封装到Result当中
        return Result.success(users1);
    }*/
    /*
    多条件查询

     */
    //@GetMapping ("/SelectMore")
    /*
    @RequestParam根据路径参数去进行查询
     */
/*
    public Result SelectMore(@RequestParam String username,@RequestParam String name) {
        User users1= userService.SelectMore(username,name);
        //将结果封装到Result当中
        return Result.success(users1);
    }
*/
    /*
    多条件模糊查询
     */
    //进行多条件查询的时候 要在userMapper当中的参数要加@Param注解
   /* @GetMapping ("/SeletcByMo")
    public Result SeletcByMo(@RequestParam String username,@RequestParam String name) {
        List<User> users = userService.SeletcByMo(username,name);
        return Result.success(users);
    }*/


}
